
/// @file    serverIf.c    
/// @brief   tcp服务线程代码  
///  
/// 实现tcp服务线程相关接口   

#include <iostream>
using namespace std;


#ifdef __cplusplus
extern "C" {               // 告诉编译器下列代码要以C链接约定的模式进行链接
#endif


#include "serverIf.h"  
#include "command.h"  
#include <sys/socket.h>  
#include <stdio.h>  
#include <string.h>  
#include <errno.h>  

#ifdef __cplusplus
}
#endif

int add_new_tcp_process_thd(serverEnv *env){
	pthread_t tcpThr; 
	if(pthread_create( &tcpThr,NULL,tcpServerThrFxn,env)){
		cerr<<"tcp thread create fail"<<endl;
		return -1;
	}
	cout<<"tcp thread has been created"<<endl;
	return 0;
	
}

int save_user_name(char *pUsername){
	count<<"user name saved,username="<<pUsername<<endl;
	return 0;
	
}

int save_user_age(int age){
	count<<"user age saved,userage="<<age<<endl;
	return 0;
}

void * tcpServerThrFxn( void * arg ){
	serverEnv *env = (serverEnv*)arg;
	int socketfd = env->m_hSocket;
	
	int returnBytes;
	
	serverPack sPack;
	returnPack rPack;
	
	memcpy(rPack.cmdHeader, tcp_cmd_header, tcp_cmd_header_len);
	
	while(1){
		//read cmd from client
		returnBytes = recv(socketfd, (uint8_t*)&sPack, server_pack_len, 0);
		if(returnBytes == server_pack_len){
			count<<"recv bytes of"<<returnBytes<<endl;
		}else if(returnBytes <= 0 && errno != EINTR && errno != EWOULDBLOCK && errno != EAGAIN){
			cerr<<"disconnected or error occur! errno="<<errno<<endl;
			break;
		}else{
			continue;
		}
		
		//check header
		if ( memcmp( sPack.cmdHeader, tcp_cmd_header, tcp_cmd_header_len) !=0){
			rPack.returnCMD = DVS_RETURN_INVLID_HEADER;  
			 // return error info to client  
			 returnBytes = send(socketfd,(uint8_t *)&rPack, return_pack_len, 0);
			 if(returnBytes < return_pack_len){
				 cerr<<"send error!"<<endl;
				 continue;
			 }
		}
		//analyse cmd
		rPack.returnCMD = DVS_RETURN_SUCCESS;
		switch(sPack.serverCMD){
			case CMD_SAVE_USER_NAME:  
				if(save_user_name(sPack.Parameters.UserName.username) != 0){
					rPack.returnCMD = DVS_RETURN_FAIL;
				}
				break;
			case CMD_SAVE_USER_AGE:
			    if( save_user_age(sPack.Parameters.UserAge.userage) != 0)  {
					rPack.returnCMD = DVS_RETURN_FAIL;  					
				}
				 break;  
          default:  
				rPack.returnCMD = DVS_RETURN_INVLID_CMD;  
				break;
			
		}
		 // return result info to client  
		 returnBytes = send(socketfd,(uint8_t *)&rPack,return_pack_len,0 );  
		 if( returnBytes < return_pack_len){
			  cerr<<"send error!"<<endl;
				 continue;
		 }
	}
	
	count<<"close session socket""<<endl;
	
	close(socketfd);
	return (void*)0;
	
}



